﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Beeldbankmvc.Code;
using Beeldbankmvc.Helpers;
using Beeldbankmvc.Models;
using System.Configuration;

namespace Beeldbankmvc.ViewModels
{
    // Used Bind excludes for dropdown boxes, otherwise a empty model could not be created
    //
    // http://stackoverflow.com/questions/331276/server-error-in-application-no-parameterless-constructor-defined-for-this-ob
    //
    [Bind(Exclude = "AvailableTypes,AvailableFormats,AvailableDeliveryMethods,AvailableFinishing")]
    public class MediaObjectViewModel
    {
        BeeldbankLinqDataContext beeldBankDB = new BeeldbankLinqDataContext();
        StatusRepository StatusRep = new StatusRepository();
        GebiedRepository GebiedRep = new GebiedRepository();

        public BEELDBANK_MEDIAOBJECT MediaObject { get; private set; }
        public string GoogleMaps { get; private set; }
        public int mapId { get; private set; }
        public MultiSelectList AllCollectionItems { get; private set; }
        public MultiSelectList SelectedCollectionItems { get; private set; }

        public SelectList Types { get; private set; }

        public String currentStatus { get; set; }

        public SelectList Statuses { get; private set; }
        public SelectList RolesList { get; set; }
        public SelectList Montage { get; set; }

        public SelectList Reaction { get; set; }
        public List<BEELDBANK_REACTIE> reactionObjects { get; set; }

        public SelectList AvailableTypes { get; set; }
        public SelectList AvailableFormats { get; set; }
        public SelectList AvailableDeliveryMethods { get; set; }
        public SelectList AvailableFinishing { get; set; }
        

        public Boolean hasNextPage { get; set; }
        public Boolean hasPreviousPage { get; set; }
        public Boolean hasSearchResults { get; set; }
        public Boolean hasMapResults { get; set; }

        public bool CanBeEditedByCurrentUser { get; set; }
        public bool MultipleRecordsExistWithCurrentTitle { get; set; }

        // used for reactions on detail page
        [Required(ErrorMessage = "Emailadres is verplicht")]
        [DataType(DataType.EmailAddress)]
        [EmailValidation(ErrorMessage = "Geen valide Email Address")]
        [DisplayName("Emailadres *")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Naam is verplicht")]
        [DataType(DataType.Text)]
        [DisplayName("Naam *")]
        public string Name { get; set; }

        [DataType(DataType.Text)]
        [DisplayName("Telefoon")]
        public string Telephone { get; set; }

        [DataType(DataType.MultilineText)]
        [DisplayName("Bericht *")]
        public string Message { get; set; }

        public SelectList AvailableRegioFacets { get; set; }
        public SelectList AvailableTechniekFacets { get; set; }
        public SelectList AvailableRiviergebiedFacets { get; set; }
        public SelectList AvailableProjectFacets { get; set; }

        public void updateFinishing(string selectedType)
        {
            // 16 = analoog, 19 = digitale foto, 20 = video
            if ((MediaObject.TypeId == (int)Mediatypes.MediaTypes.analog) // 16 = analoog
                ||
                (MediaObject.TypeId == (int)Mediatypes.MediaTypes.digital)// 19 = digitaal
                )
            {
                if (selectedType != null && selectedType.StartsWith("Scan"))
                {
                    SelectList selectlistFinishing = new SelectList(
                        new[]
                    {
                        new { Id = "scan via FTP", Name = "scan via FTP" },
                        new { Id = "scan via post", Name = "scan via post" },
                    }
                        , "Id", "Name");

                    AvailableFinishing = selectlistFinishing;
                }
                else
                {
                    SelectList selectlistFinishing = null;

                    AvailableFinishing = selectlistFinishing;
                }
            }
            else if (MediaObject.TypeId == (int)Mediatypes.MediaTypes.video_animation)
            {
                SelectList selectlistFinishing = null;

                AvailableFinishing = selectlistFinishing;
            }
        }

        public MediaObjectViewModel()
        {
        }

        public MediaObjectViewModel(BEELDBANK_MEDIAOBJECT mediaobject)
        {
            MediaObject = mediaobject;

            if (MediaObject.Latitude.HasValue)
            {
                try
                {
                    string Latitude = MediaObject.Latitude.ToString().Replace(",", ".");
                    string Longitude = MediaObject.Longitude.ToString().Replace(",", ".");

                    // Conversion from decimal to degrees
                    string LatDeg = Convert.ToInt32(MediaObject.Latitude).ToString() + " ";
                    string LatMin = Convert.ToInt32((MediaObject.Latitude % 1) * 60).ToString() + "' ";
                    string LatSec = Convert.ToInt32((((MediaObject.Latitude % 1) * 60) % 1) * 60).ToString() + "\" N, ";
                    string LongDeg = Convert.ToInt32(MediaObject.Longitude).ToString() + " ";
                    string LongMin = Convert.ToInt32((MediaObject.Longitude % 1) * 60).ToString() + "' ";
                    string LongSec = Convert.ToInt32((((MediaObject.Longitude % 1) * 60) % 1) * 60).ToString() + "\" E";

                    string Hoogte = "";
                    if (MediaObject.Hoogte.HasValue)
                        Hoogte = "<strong>Hoogte:</strong> " + MediaObject.Hoogte.ToString() + " meter<br />";
                    string Datum = "";
                    if (MediaObject.Datum_Realisatie.ToString() != "01-01-1900")
                        Datum = "<strong>Datum:</strong> " + String.Format("{0:d}", MediaObject.Datum_Realisatie) + "<br />";
                    string Zoom = "8";
                    if (MediaObject.GoogleZoom.HasValue)
                        Zoom = MediaObject.GoogleZoom.ToString();
  
                    string tmpString = "<strong><abbr title='Global Positioning Satellite'>GPS</abbr>:</strong> "
                        + "<a title='Externe doorverwijzing naar de lokatie op Google maps (opent in nieuw venster)' href='http://maps.google.com/maps?f=q&amp;hl=nl&amp;z=" + Zoom + "&amp;q=" + Latitude + "," + Longitude + "' >" + LatDeg + LatMin + LatSec + LongDeg + LongMin + LongSec + "</a><br />" + Hoogte + Datum;
                    
                    // This is a static link to Google maps
                    //tmpString += "<a title='Externe doorverwijzing naar de lokatie op Google maps (opent in nieuw venster)' href='http://maps.google.com/maps?f=q&amp;hl=nl&amp;z=" + Zoom + "&amp;q=" + Latitude + "," + Longitude + "' ><strong>Toon lokatie op Google maps</strong></a>";

                    // Fill mapId such that we are able to generate a detail location on the map
                    mapId = GebiedRep.MapByLocation(MediaObject.Latitude.Value, mediaobject.Longitude.Value);
                    //if (mapId != 0)
                    //    // Display link to detail image
                    //    tmpString += "<br /><strong><a title='Interne doorverwijzing naar de detailkaart waar dit object zich bevindt.' href='/Gebied/SelectYear?id=" + mapId.ToString() + "&amp;year=" + MediaObject.Datum_Realisatie.Value.Year.ToString() + "'>Toon lokatie op detailkaart</a></strong>";

                    // This url does in include of Google on the page
                    //tmpString += "<br /><iframe title='Detail lokatie op de kaart van Nederland waar de foto genomen is.' width='216' height='216' frameborder='0' scrolling='no' marginheight='0' marginwidth='0' src='https://maps.google.com/?ie=UTF8&amp;center=" + Latitude + "," + Longitude + "&amp;q=" + Latitude + "," + Longitude + "&amp;t=h&amp;z=16&amp;markers=size:mid|color:0xFFFF00||&amp;output=embed'></iframe>";
                    // This url was the latest version, which added a static image and a link to Google displaying the selected location on the screen.
                    //tmpString += "<a title='Externe doorverwijzing naar de lokatie op Google maps (opent in nieuw venster)' href='http://maps.google.com/maps?f=q&amp;hl=nl&amp;z=" + Zoom + "&amp;q=" + Latitude + "," + Longitude + "' ><img src='https://maps.google.com/maps/api/staticmap?center=" + Latitude + "," + Longitude + "&amp;zoom=" + Zoom + "&amp;size=216x216&amp;maptype=hybrid&amp;sensor=false&amp;markers=size:mid|color:0xFFFF00||" + Latitude + "," + Longitude + "'></a>";

                    GoogleMaps = tmpString;
                }
                catch
                {
                    GoogleMaps = "";
                }
            }
            else
                GoogleMaps = "";

            CollectionRepository collectionRepository = new CollectionRepository();

            var allCollection = collectionRepository.FindAllSortedByName();
            AllCollectionItems = new MultiSelectList(allCollection, "Id", "Name");

            // TODO: find related collections
            var selectedCollection = collectionRepository.FindCollections(MediaObject.Id);
            SelectedCollectionItems = new MultiSelectList(selectedCollection, "CollectionId", "CollectionName");
            
            //
            // Type Dropdown
            //
            MediaTypeRepository mediatypeRepository = new MediaTypeRepository();
            var allTypes = mediatypeRepository.FindAll();
            Types = new SelectList(allTypes, "Id", "Name", MediaObject.TypeId);

            StatusRepository statusRepository = new StatusRepository();
            //
            // Status Current
            //
            if (MediaObject.StatusId != 0)
                currentStatus = statusRepository.FindOne(MediaObject.StatusId).Name;

            //
            // Status Dropdown
            //
            if (Roles.IsUserInRole("Beheerder") && !Roles.IsUserInRole("EindRedacteur") && !Roles.IsUserInRole("Administrator"))
            {
                var allStatus = statusRepository.FindAllByRol("Beheerder");
                Statuses = new SelectList(allStatus, "Id", "Name");
            }
            else if (Roles.IsUserInRole("EindRedacteur") && !Roles.IsUserInRole("Administrator"))
            {
                var allStatus = statusRepository.FindAllByRol("EindRedacteur");
                Statuses = new SelectList(allStatus, "Id", "Name");
            }
            else
            {
                var allStatus = statusRepository.FindAll();
                Statuses = new SelectList(allStatus, "Id", "Name");
            }
            
            //
            // Roles Dropdown
            //
            UserRepository userRepository = new UserRepository();
            var allRoles = userRepository.GetAllRolles();
            RolesList = new SelectList(allRoles, MediaObject.GroepRechten); // MediaObject.StatusId

            //
            // Reaction Dropdown
            //
            SelectList itemList = new SelectList(
                new[]
                {
                    new { Id = "1", Name = "Nog te verwerken" },
                    new { Id = "2", Name = "Verwerkt" },
                    new { Id = "3", Name = "Afgewezen" },
                }
                , "Id", "Name");
            Reaction = itemList;

            // Select reactions for this media object

            if (Membership.GetUser() != null)
            {
                try
                {
                    ReactionRepository reactionRepository = new ReactionRepository();
                    reactionObjects = reactionRepository.FindNewReactionsForMediaObject(MediaObject.Id, Membership.GetUser().UserName).ToList();
                }
                catch
                {
                }
            }
            
            //
            // Finishing Dropdown - always select a finishing
            //
            SelectList selectlistFinishing = new SelectList(
            new[]
                {
                    new { Id = 0, Name = "" },
                }
            , "Id", "Name");
            AvailableFinishing = selectlistFinishing;

            //
            // Montage Dropdown
            //
            Montage = new SelectList(
                new[]
                {
                    new { Id = "Gemonteerd, 4x3 (320)", Name = "Gemonteerd, 4x3 (320)" },
                    new { Id = "Gemonteerd, 4x3 (400)", Name = "Gemonteerd, 4x3 (400)" },
                    new { Id = "Gemonteerd, 16x9 (320)", Name = "Gemonteerd, 16x9 (320)" },
                    new { Id = "Gemonteerd, 16x9 (400)", Name = "Gemonteerd, 16x9 (400)" },

                    new { Id = "Ongemonteerd, 4x3 (320)", Name = "Ongemonteerd, 4x3 (320)" },
                    new { Id = "Ongemonteerd, 4x3 (400)", Name = "Ongemonteerd, 4x3 (400)" },
                    new { Id = "Ongemonteerd, 16x9 (320)", Name = "Ongemonteerd, 16x9 (320)" },
                    new { Id = "Ongemonteerd, 16x9 (400)", Name = "Ongemonteerd, 16x9 (400)" }
                }
                , "Id", "Name", MediaObject.Montage);

            //
            // Facets Dropdowns
            //
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();
            
            RegioFacetRepository facetRegioRepository = new RegioFacetRepository();
            var allRegios = facetRegioRepository.getAllRegios();
            if (allFacets != null)
                AvailableRegioFacets = new SelectList(allRegios, "Id", "Description", allFacets.RegioFacetId);
            else
                AvailableRegioFacets = new SelectList(allRegios, "Id", "Description");

            TechniekFacetRepository techniekFacetRepository = new TechniekFacetRepository();
            var allTechniek = techniekFacetRepository.getAllTechniek();
            if (allFacets != null)
                AvailableTechniekFacets = new SelectList(allTechniek, "Id", "Description", allFacets.TechniekFacetId);
            else
                AvailableTechniekFacets = new SelectList(allTechniek, "Id", "Description");
            
            RiviergebiedFacetRepository riviergebiedFacetRepository = new RiviergebiedFacetRepository();
            var allRiviergebied = riviergebiedFacetRepository.getAllRiviergebied();
            if (allFacets != null)
                AvailableRiviergebiedFacets = new SelectList(allRiviergebied, "Id", "Description", allFacets.RiviergebiedFacetId);
            else
                AvailableRiviergebiedFacets = new SelectList(allRiviergebied, "Id", "Description");
            
            ProjectFacetRepository facetProjectRepository = new ProjectFacetRepository();
            var allProject = facetProjectRepository.getAllProject(ConfigurationManager.AppSettings["publicationName"]);
            if (allFacets != null)
                AvailableProjectFacets = new SelectList(allProject, "Id", "Description", allFacets.ProjectFacetId);
            else
                AvailableProjectFacets = new SelectList(allProject, "Id", "Description");
        }

        public String getStatusName()
        {
            return StatusRep.FindOne(MediaObject.StatusId).Name;
        }

        public String getRegio()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            RegioRepository regioRepository = new RegioRepository();
            if ((allFacets != null) && (allFacets.RegioFacetId.HasValue))
                return regioRepository.FindRegioName(allFacets.RegioFacetId.Value);
            else
                return "";
        }

        public bool hasRegio()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            if ((allFacets != null) && (allFacets.RegioFacetId.HasValue))
                return true;
            else
                return false;
        }

        public String getProject()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            ProjectRepository projectRepository = new ProjectRepository();
            if ((allFacets != null) && (allFacets.ProjectFacetId.HasValue))
                return projectRepository.FindProjectName(allFacets.ProjectFacetId.Value);
            else
                return "";
        }

        public bool hasProject()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            if ((allFacets != null) && (allFacets.ProjectFacetId.HasValue))
                return true;
            else
                return false;
        }

        public String getTechniek()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            TechniekRepository techniekRepository = new TechniekRepository();
            if ((allFacets != null) && (allFacets.TechniekFacetId.HasValue))
                return techniekRepository.FindTechniekName(allFacets.TechniekFacetId.Value);
            else
                return "";
        }

        public bool hasTechniek()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            if ((allFacets != null) && (allFacets.TechniekFacetId.HasValue))
                return true;
            else
                return false;
        }

        public String getRiviergebied()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            RiviergebiedRepository riviergebiedRepository = new RiviergebiedRepository();
            if ((allFacets != null) && (allFacets.RiviergebiedFacetId.HasValue))
                return riviergebiedRepository.FindRiviergebiedName(allFacets.RiviergebiedFacetId.Value);
            else
                return "";
        }

        public bool hasRiviergebied()
        {
            FacetRepository facetRepository = new FacetRepository();
            var allFacets = facetRepository.getAllFacets(MediaObject.Id).FirstOrDefault();

            if ((allFacets != null) && (allFacets.RiviergebiedFacetId.HasValue))
                return true;
            else
                return false;
        }

        public String getTypeName()
        {
            String retVal = "";

            switch (MediaObject.TypeId)
            {
                case Constants.ITEM_TYPE_ANALOG:
                    retVal = "Analoge Foto";
                    break;
                case Constants.ITEM_TYPE_DIGITAL:
                    retVal = "Digitale Foto";
                    break;
                case Constants.ITEM_TYPE_VIDEO:
                    retVal = "Video/Animatie";
                    break;
                case Constants.ITEM_TYPE_ILLUSTRATION:
                    retVal = "Kaart/Illustratie";
                    break;
            }
            return retVal;
        }

    }
}
